# -*- coding: iso-8859-1 -*-
#
#    This is part of Malvinas Argentinas Messenger
#
#    Malvinas Argentinas Messenger is free software; you can redistribute
#    it and/or modify it under the terms of the GNU General Public License
#    as published by the Free Software Foundation; either version 2 of the
#    License, or (at your option) any later version.
#
#    Malvinas Argentinas Messenger is distributed in the hope that it will be
#    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Malvinas Argentinas Messenger; if not, write to the Free
#    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
#    MA  02110-1301  USA

#/--------\
# IMPORTS |
#\--------/

import curses
import datetime, time
import sys, os
import socket, select
from protocol import msnlib, msncb, msnobj, msndp, msnft
from ui import backEnd
import callbacks
from listManager import listManager
import gettext
_ = gettext.gettext

class ConnectionManager:
	def __init__(self, mam):
		self.mam = mam
		self.connectStatus = 0
		self.connect()
		# Set privacy
		self.mam.m.privacy()
		# Set next ping time
		self.nextPing = datetime.datetime.now () + datetime.timedelta(seconds = 30) 
		# We will show list after got all the ILN's. Well, that is what we'll try.
		# We wait 1 second per 50 contacts in list. Obviously those are not online 
		# contacts, just used for statistics.
		secs = max(self.mam.m.lst_total, 50) / 50
		self.listOK = 0
		self.timelistOK = datetime.datetime.now () + datetime.timedelta(seconds = secs)

	def connect(self, stat = ''):
		# I show progress of connection in the Events tab.
		self.mam.ui.printMsg('%s Malvinas Argentinas Messenger' % _("Starting"), self.mam.ui.COLORS.STARTUP)
		self.mam.ui.padArray.refresh(_('EVENTS'))

		# Check in config if we have the user
		if self.mam.config.has_key('email'):
			self.mam.m.email = self.mam.config['email']
		# If we do not, we ask for them
		else:
			try:
				self.mam.m.email = self.mam.ui.askPassport()
			except KeyboardInterrupt:
				self.mam.ui.quit(0)

		# Check in config if we have the pass
		if self.mam.config.has_key('password'):
			self.mam.m.pwd = self.mam.config['password']
		# If we do not, we ask for them
		else:
			try:
				self.mam.m.pwd = self.mam.ui.askPassword()

			except KeyboardInterrupt:
				self.mam.ui.quit(0)
		
		# Now we got user and pass, we try to connect
		try:
			self.mam.ui.printMsg('\n%s...' % _("Connecting to server"), self.mam.ui.COLORS.WHITE_RI)
			self.mam.ui.padArray.refresh(_('EVENTS'))
			self.mam.ui.padInput.refresh()
			self.mam.m.login()
			self.mam.ui.padArray.wins[1].ventana.erase()
			self.mam.ui.printMsg('%s Malvinas Argentinas Messenger' % _("Starting"), self.mam.ui.COLORS.STARTUP)
			self.mam.ui.printMsg('\n%s...' % _("Connecting to server"), self.mam.ui.COLORS.WHITE_R)
			self.mam.ui.printMsg(' %s.' % _('Done'), self.mam.ui.COLORS.BLACK_R)
			self.mam.ui.padArray.refresh(_('EVENTS'))
			self.mam.ui.padInput.refresh()
		except 'AuthError', info:
			errno = int(info[0])
			if not msncb.error_table.has_key(errno):
				desc = 'Unknown'
			else:
				desc = msncb.error_table[errno]
			self.mam.ui.printMsg(' Error: %s (%s)' % (desc, errno), self.mam.ui.COLORS.RED_R)
			self.mam.ui.padArray.refresh(_('EVENTS'))
			time.sleep(3)
			self.mam.ui.quit(1)
		except KeyboardInterrupt:
			self.mam.ui.quit(1)
		except ('SocketError', socket.error), info:
			self.mam.ui.printMsg(' %s: ' % _("Network error") + str(info), self.mam.ui.COLORS.RED_R)
			self.mam.ui.padArray.refresh(_('EVENTS'))
			time.sleep(3)
			self.mam.ui.quit(1)
		except:
			self.mam.ui.printMsg(' %s...' % _("Error connecting to server"), self.mam.ui.COLORS.RED_R)
			self.mam.ui.padArray.refresh(_('EVENTS'))
			time.sleep(3)
			self.mam.ui.quit(1)

		# We do the sync with verbosity
		self.syncList()

		# We build the File transfer list
		#self.mam.ft = msnft.transferList()

		# We build the MsnObject and change to our initial status
		if stat == '':
			status = msnlib.reverse_status[self.mam.ui.status]
		else:
			status = msnlib.reverse_status[stat]
		if int(self.mam.config['show_picture']) == 0:
			self.mam.ui.msn_obj = ''
		else:
			# Build Display Picture Manager
			self.mam.dpManager = msndp.dpManager()
			try:
				os.system ("cp " + self.mam.config['picture_name'] + " " + sys.path[0] + "/.picture.tmp")
				mo = msnobj.Msnobj(self.mam.ui, self.mam.m)
				self.mam.ui.msn_obj = ' 1615642660 ' + mo.quote()
			except:				
				self.mam.ui.printMsg('\n%s' % _('Error building MsnObject'), self.mam.ui.COLORS.RED_R)
				self.mam.ui.padArray.refresh(_('EVENTS'))
				self.mam.ui.msn_obj = ''

		if self.mam.m.change_status(status, self.mam.ui.msn_obj):
			ctime = time.strftime(self.mam.config['timestamp_format'], time.localtime())
			self.mam.ui.printMsg('\n%s ' % ctime, self.mam.ui.COLORS.WHITE)
			status = _(status)
			self.mam.ui.printMsg('%s ' % _('Status set to'), self.mam.ui.COLORS.WHITE_R)
			self.mam.ui.printMsg(status, self.mam.ui.COLORS.CYAN_R)
		else:
			self.mam.ui.printMsg('\n%s' % _('Error setting status: unknown status') + ' %s' % status, self.mam.ui.COLORS.RED_R)
		self.connectStatus = 1
		self.mam.ui.padArray.refresh(_('EVENTS'))
		self.mam.ui.padInput.refresh()

	def syncList(self, verbosity = 1, resync = 0):
		if self.mam.m.sync():
			list_complete = 0
		else:
			self.mam.ui.printMsg('\n%s.' % _("Error syncing users"), self.mam.ui.COLORS.RED_R)
			self.mam.ui.padArray.refresh(_('EVENTS'))
			time.sleep(3)
			self.mam.ui.quit(1)
	
		if verbosity:
			self.mam.ui.printMsg('\n%s...' % _('Getting and building the list'), self.mam.ui.COLORS.WHITE_R)
			self.mam.ui.padArray.refresh(_('EVENTS'))
		# Get the list
		while list_complete == 0:
			#if not resync:
			fds = self.mam.m.pollable()
			infd = fds[0]
			outfd = fds[1]
			for i in fds[0] + fds[1]:
				self.mam.m.read(i)
				#self.mam.ui.printMsg(str(i))
				#self.mam.ui.padArray.refresh(_('EVENTS'))
				if not list_complete and self.mam.m.lst_total == self.mam.m.syn_total:
					list_complete = 1
					break
		
		# Here we build our list from the data received
		self.mam.ui.scrList.entireList = []
		self.mam.ui.scrList.visibleList = []
		self.mam.ui.scrList.default_scrListpos = 0
		self.mam.ui.scrList.list_lines = 0
		self.mam.contactListManager = listManager(self.mam.ui)
		self.mam.contactListManager.make_List()
		if resync:
			self.mam.ui.scrList.build_entire_scrList()
			self.mam.ui.scrList.build_visible_scrList()
			self.mam.ui.scrList.print_scrList()
		if verbosity:
			self.mam.ui.printMsg(' %s.' % _("Done"), self.mam.ui.COLORS.BLACK_R)
			self.mam.ui.padArray.refresh(_('EVENTS'))

	# The infinite loop as a calling method.
	# Read input from stdin and the main process.
	def infiniteLoop(self):
		while 1:
			self.fds = self.mam.m.pollable()
			infd = self.fds[0]
			outfd = self.fds[1]
			infd.append(sys.stdin)
			try:
				self.fds = select.select(infd, outfd, [], 2)
			except select.error:
				continue
			except KeyboardInterrupt:
				self.mam.ui.printMsg('%s.' % _('KEYBOARD Interrupt'))
				self.mam.ui.quit(0)
			except:
				self.mam.ui.printMsg('%s * 1. %s.' % (_('ERROR'), _('Please inform')))
			for i in self.fds[0] + self.fds[1]:
				if i == sys.stdin:
					# No descomentar
					#try:
						self.mam.lastUserInteraction = datetime.datetime.now()
						carac = self.mam.ui.padInput.p.getch()
						if self.listOK:
							self.mam.stdinManager.manageInput(carac)
					#except Exception, err:
					#	self.mam.ui.printMsg('\n%s.' % err, \
					#	self.mam.ui.COLORS.RED_R)
					#	self.mam.ui.padArray.refresh(_('EVENTS'))
				else:
					try:
						if self.connectStatus:
							self.mam.m.read(i)
					except ('SocketError', socket.error), err:
						pass
						#Comentado 14/12/2008
						#if i != self.mam.m:
						#	self.mam.ui.printMsg('\n%s ' % _('Socket warning: Connection with') + '%s ' % i.emails[0] + \
						#	'%s.' % _('closed suddenly'), self.mam.ui.COLORS.RED_R)
						#	self.mam.ui.padArray.refresh(_('EVENTS'))
						#	if i.msgqueue:
						#		self.mam.ui.printMsg('\n%s.' % _('We had msgs too'), \
						#		self.mam.ui.COLORS.RED_R)
						#		self.mam.ui.padArray.refresh(_('EVENTS'))
						#	self.mam.m.close(i)
						#else:
						#	self.mam.ui.printMsg('\n%s!' % _('Main socket closed') + '%s...' % _('Trying reconnection'), \
						#	self.mam.ui.COLORS.RED_R)
						#	self.mam.ui.padArray.refresh(_('EVENTS'))
						#	self.mam.m.status = 'FLN'
						#	self.mam.ui.print_Status(self.mam.m.status, self.mam.ui.statusToColor(self.mam.m.status))
						#	#self.connect()		# Reconnecting to MSN server
					except (), err:
						self.mam.ui.printMsg('\n%s: ' % _('ERROR') + '%s. ' % err + _('Please inform'))
						self.mam.ui.padArray.refresh(_('EVENTS'))

			# Because MSNP9 is so shitty in this ILN's matter,
			# We have to put this for connection :@
			if not self.listOK and datetime.datetime.now() > self.timelistOK:
				self.mam.ui.padArray.wins[0].ventana.erase()
				self.mam.ui.scrList.build_entire_scrList()
				self.mam.ui.scrList.build_visible_scrList()
				# Now everything went ok, we can delete the logo and 
				# finish building the interface
				self.mam.ui.winLogo.erase()
				self.mam.ui.winLogo.refresh()
				del self.mam.ui.winLogo
				self.listOK = 1
				# Refresh interface
				self.mam.ui.refreshScr()

			# Refresh time
			# Modificado 14/12/2008
			if self.connectStatus and self.listOK and \
			self.mam.ui.padArray.idactive in (0, 1) and \
			int(self.mam.config['show_time']) == 1:
				self.mam.ui.show_time()
			#	self.mam.ui.refreshScr(0, 0, 0, 1, 0, 0, 1, 1)

			# Check if its time to send a ping	
			if self.connectStatus and datetime.datetime.now() > self.nextPing \
			and not self.mam.ui.options_win:
				self.nextPing = datetime.datetime.now () + datetime.timedelta(seconds = 60)
				try:
					self.mam.m._send_wot('PNG')
				except:
					self.mam.ui.printMsg('\n%s' % _('Socket error sending ping. The connection has probably been closed.'), self.mam.ui.COLORS.BLACK_R)
					self.mam.ui.printMsg('\n%s...' % _('Trying reconnection'), self.mam.ui.COLORS.WHITE_R)
					self.mam.ui.padArray.refresh(_('EVENTS'))
					self.mam.m.status = 'FLN'
					self.mam.ui.print_Status(self.mam.m.status, self.mam.ui.statusToColor(self.mam.m.status))
					self.connect()		# Reconnecting to MSN server

			# Check if its time to resync the list
			#if self.connectStatus and datetime.datetime.now() > self.mam.lastUserInteraction + \
			#datetime.timedelta(minutes=1):
			#		self.mam.lastUserInteraction = datetime.datetime.now()
					# Server does not reply to this fucking sync !
					#self.mam.m._send('SYN', '0')
					#.... str(self.mam.m.syn_lver))
